/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package estrutura;

import java.io.Serializable;
import java.util.Collection;
import java.util.LinkedList;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 * Classe cujos objetos são as matérias disponibilizadas pela Unicamp.
 * @author Fábio
 */
@Entity
@Table(name = "MATERIAS")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Materias.findAll", query = "SELECT m FROM Materias m"),
    @NamedQuery(name = "Materias.findBySigla", query = "SELECT m FROM Materias m WHERE m.sigla = :sigla"),
    @NamedQuery(name = "Materias.findByCreditos", query = "SELECT m FROM Materias m WHERE m.creditos = :creditos")})
public class Materias implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * Sigla da disciplina.
     */
    @Id
    @Basic(optional = false)
    @Column(name = "SIGLA")
    private String sigla;
    /**
     * Quantidade de créditos da disciplina.
     */
    @Column(name = "CREDITOS")
    private Integer creditos;
    /**
     * Continências e equivalências da disciplina.
     */
    @JoinTable(name = "EQUIVALENCIAS", joinColumns = {
        @JoinColumn(name = "DISCIPLINA", referencedColumnName = "SIGLA")}, inverseJoinColumns = {
        @JoinColumn(name = "ID_GRUPO", referencedColumnName = "ID")})
    @ManyToMany
    private Collection<Grupo> continencias;
    /**
     * Pré-requisitos da disciplina.
     */
    @JoinTable(name = "PREREQUISITOS", joinColumns = {
        @JoinColumn(name = "DISCIPLINA", referencedColumnName = "SIGLA")}, inverseJoinColumns = {
        @JoinColumn(name = "ID_GRUPO", referencedColumnName = "ID")})
    @ManyToMany
    private Collection<Grupo> preReqs;
    /**
     * Turmas que a disciplina possui.
     */
    @JoinTable(name = "TURMAS_DISCIPLINAS", joinColumns = {
        @JoinColumn(name = "DISCIPLINA", referencedColumnName = "SIGLA")}, inverseJoinColumns = {
        @JoinColumn(name = "ID_TURMA", referencedColumnName = "ID")})
    @ManyToMany
    private Collection<Turma> turmas;
    
    /**
     * Contrutor sem parametros
     */
    public Materias() {
    }
    
    /**
     * Contrutor utilizando sigla
     */
    public Materias(String sigla) {
        this.sigla = sigla;
    }
    
    /**
     * Contrutor utilizando sigla e créditos
     */
    public Materias(String sigla, Integer creditos) {
        this.sigla = sigla;
        this.creditos = creditos;
    }

    /** Retorna sigla da matérias
     * @return String - Sigla da matéria
     */
    public String getSigla() {
        return sigla;
    }
    
    /**Define um sigla para a matéria*/
    public void setSigla(String sigla) {
        this.sigla = sigla;
    }

    /**Retorna numero de creditos da materia
     * @return Integer - numero de créditos
     */
    public Integer getCreditos() {
        return creditos;
    }
    
    /**Define numero de creditos da materia*/
    public void setCreditos(Integer creditos) {
        this.creditos = creditos;
    }

    @XmlTransient
    /**Retorna o grupo de continências
     * @return Collection - Lista de matérias que são equivalentes
     */
    public Collection<Grupo> getContinencias() {
        return continencias;
    }
    
    /**Define lista de matérias esquivalente
     * @param grupoCollection*/
    public void setContinencias(Collection<Grupo> grupoCollection) {
        this.continencias = grupoCollection;
    }

    @XmlTransient
    /**Retorna o grupo de pré requisitos
     * @return Collection - Lista de matérias que são prerequisitos
     */
    public Collection<Grupo> getPreReqs() {
        return preReqs;
    }
    
    /**Define lista de pre-requisito
     * @param grupoCollection*/
    public void setPreReqs(Collection<Grupo> grupoCollection) {
        this.preReqs = grupoCollection;
    }
    
    /**
     * Adiciona um novo pré-requisito
     * @param preReq Grupo de pré-requisito a ser adicionado
     * @return true Caso a adição seja bem sucedida.
     */
    public boolean addPreReq(Grupo preReq) {
        if (preReqs == null) {
            preReqs = new LinkedList<>();
        }
        return this.preReqs.add(preReq);
    }
    
    /**
     * Adiciona uma nova continência para a disciplina
     * @param cont Grupo de continência a ser adicionada
     * @return true Caso a adição seja bem sucedida.
     */
    public boolean addContinencia(Grupo cont) {
        if (continencias == null) {
            continencias = new LinkedList<>();
        }
        return this.continencias.add(cont);
    }
    
    /**
     * Adiciona uma nova turma para a disciplina.
     * @param sala Turma a ser adicionada.
     */
    public void setTurma(Turma sala) {
        if (this.turmas == null) {
            turmas = new LinkedList<>();
        }
        this.turmas.add(sala);
    }

    /**
     * Retorna as turmas que a disciplina possui.
     * @return Retorna uma coleção de turmas, que são as turmas que a disciplina
     * possui.
     */
    public Collection<Turma> getTurma() {
        return turmas;
    }
    

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (sigla != null ? sigla.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof Materias)) {
            return false;
        }
        Materias other = (Materias) object;
        return (this.sigla != null || other.sigla == null) && (this.sigla == null || this.sigla.equalsIgnoreCase(other.sigla));
    }

    @Override
    public String toString() {
        return "estrutura.Materias[ sigla=" + sigla + " ]";
    }

}
